-- UIAirShipHandBook
-- Create by dengc
-- 飞艇图鉴

require "game/ui/form/sky_city/UIShipDesc"

-- UIAirShipHandBook继承自Layer
UIAirShipHandBook = class("UIAirShipHandBook", function()
    return cc.Layer:create();
end);

function UIAirShipHandBook.create(pageType, selectIndex)
    return UIAirShipHandBook.new(pageType, selectIndex);
end

-- 分页的数量
local TAB_NUM = 4;

-- 分页标签
local TYPE_ALL     = 4; -- 全部
local TYPE_SCIENCE = 1; -- 科技类
local TYPE_SPECIAL = 2; -- 特种类
local TYPE_MAGIC   = 3; -- 魔法类

-- 格子相关
local ITEM_NAME       = "item";
local MIN_GRID_COLUMN = 4;

-- 标签页的顺序
local TAB_ORDER = {TYPE_ALL, TYPE_SCIENCE, TYPE_MAGIC, TYPE_SPECIAL};

-- 内部函数申明
local sortAirShips;

-- 类型与描述的映射
local typeIndexMap = {"science", "magic", "special", "all"};

-- 图鉴合图路径
local SHIP_PLIST = "images/ui/airship_hand_book.plist";

-- 构造函数
function UIAirShipHandBook:ctor(pageType, selectIndex)
    -- 初始化
    self:setName("UIAirShipHandBook");
    local node = cc.CSLoader:createNode("layout/sky_city/AirShipHandBook.csb");
    self:addChild(node);
    self.node = node;

    -- 加载合图
    cc.SpriteFrameCache:getInstance():addSpriteFrames(SHIP_PLIST);

    local CT = node:getChildByName("CT");
    local BT = node:getChildByName("BT");
    local scroll_view = findChildByName(CT, "scroll_view");

    self.CT = CT;
    self.BT = BT;
    self.scrollView = scroll_view;
    self.selectIndex = 1;      -- 当前选中的格子
    self.pageType = pageType or TYPE_ALL;  -- 当前页面的类型
    self.selectIndex = selectIndex or 1;

    -- 注册点击事件
    self:registerTouchEvent();

    -- 初始化飞艇数据
    self:initData();

    -- 重绘标签页
    self:redrawTabs();

    -- 重绘页面
    self:redraw();

    -- 重绘格子
    self:redrawGrids();

    -- 注册事件回调
    self:registerEventCallback();

    -- 适配
    self:resize();
end

-- 对飞船排序
function sortAirShips(ship1, ship2)
    if ship1.own ~= ship2.own then
        return ship1.own > ship2.own;
    elseif ship1.own == 1 and ship2.own == 1 then
        if ship1.star ~= ship2.star then
            return ship1.star > ship2.star;
        else
            return ship1.id < ship2.id;
        end
    else
        if ship1.chip ~= ship2.chip then
            return ship1.chip > ship2.chip;
        else
            return ship1.id < ship2.id;
        end
    end
end

-- 注册事件回调
function UIAirShipHandBook:registerEventCallback()
    -- 关注评论数量更新
    EventMgr.register("UIAirShipHandBook", event.UPDATE_COMMENT_COUNT, function(para)
        self:redrawCommentBtn(para);
    end);

    EventMgr.register("UIAirShipHandBook", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UIAirShipHandBook" then
            -- 显示顶部菜单
            UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_AIRSHIP_SCORE, TOPMENU_FRAME_AIRSHIP_ATTRIB, TOPMENU_FRAME_HEAD_AIRSHIP);
            
            -- 隐藏飞艇列表界面的部分显示
            local uiForm = UIMgr:getCurrentScene():getFormByName("UINewAirShipList");
            if uiForm then
                local bt2 = findChildByName(uiForm.node, "BT2");
                bt2:setVisible(false);
            end
        end
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            -- 显示隐藏的界面元素
            local uiForm = UIMgr:getCurrentScene():getFormByName("UINewAirShipList");
            if uiForm then
                local bt2 = findChildByName(uiForm.node, "BT2");
                bt2:setVisible(true);
            end

            EventMgr.removeAll("UIAirShipHandBook");
        elseif ev == "enter" then
            
        end
    end);
end

-- 初始化数据
function UIAirShipHandBook:initData()
    local data = {};     -- 所有飞艇数据
    self.typeData = {};  -- 分类型的飞艇数据
    for i = 1, TAB_NUM do
        self.typeData[i] = {};
    end

    -- 获取所有的飞艇
    data = NewAirShipM.getAllAirShips();
    for _, id in ipairs(data) do
        data[id] = {};

        -- 是否拥有
        local own = NewAirShipM.hasOwnShip(id) and 1 or 0;
        data[id]["own"] = own;

        -- 星级
        local star = NewAirShipM.getAirShipRank(id);
        data[id]["star"] = star;

        -- id
        data[id]["id"] = id;

        -- chipId
        local chipId = NewAirShipM.query(id, "chip_id");
        data[id]["chip"] = (ItemM.getAmount(ME.user, chipId) > 0) and 1 or 0;

        -- 按主炮类型分类
        local skillType = NewAirShipM.query(id, "skill_type");
        table.insert(self.typeData[skillType], data[id]);

        -- 把全部飞艇的数据插入进去
        table.insert(self.typeData[TYPE_ALL], data[id]);
    end
    
    -- 分类型排序
    for i = 1, TAB_NUM do
        table.sort(self.typeData[i], sortAirShips);
    end
end

-- 注册标签页点击回调
function UIAirShipHandBook:registerTabTouchEvent(node)
    -- 节点
    local tabImage = node:getChildByName("tab");
    local tabLight = node:getChildByName("light");
    local tabIcon = node:getChildByName("icon");
    local tabNode = findChildByName(self.node, "CT/tab");

    -- 置灰颜色
    local blendColor = TextStyleM.TEXT_COLOR_BLEND;
    local normalColor = TextStyleM.TEXT_COLOR_NORMAL;

    local function onClick(sender, eventType)
        -- 点击时的回调
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");
            -- 去除其它高亮
            for i = 1, #tabNode.rows do
                tabNode.rows[i]:getChildByName("light"):setVisible(false);
                tabNode.rows[i]:getChildByName("tab"):setColor(blendColor);
                tabNode.rows[i]:getChildByName("icon"):setColor(blendColor);
            end
            -- 设置本身高亮
            tabLight:setVisible(true);
            tabImage:setColor(normalColor);
            tabIcon:setColor(normalColor);

            -- 重绘
            self.selectIndex = 1;
            self.pageType = node.type;
            self:redraw();
            self:redrawGrids();
        end
    end

    tabImage:addTouchEventListener(onClick);
end

-- 注册点击事件
function UIAirShipHandBook:registerTouchEvent()
    local node = self.node;

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UIAirShipHandBook");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 提示
    local tipImg = findChildByName(self.CT, "tip_img");
    local function onTipClick(sender, eventType)
        if eventType == ccui.TouchEventType.began then
           tipImg:runAction(cc.ScaleTo:create(0.1, 0.97));
        elseif eventType == ccui.TouchEventType.canceled then
            tipImg:runAction(cc.ScaleTo:create(0.1, 1));
        elseif eventType == ccui.TouchEventType.ended then
            tipImg:runAction(cc.ScaleTo:create(0.1, 1));
            AudioM.playFx("button_click");
            self:showDesc();
        end
    end
    tipImg:addTouchEventListener(onTipClick);

    -- 跳转按钮点击事件
    local btnTurn = findChildByName(self.node, "BT/turn_btn");
    local function onTurnClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 跳转到飞艇列表对应的位置
            local uiForm = UIMgr:getCurrentScene():getFormByName("UINewAirShipList");
            if uiForm then
                local data = self.typeData[self.pageType][self.selectIndex];
                uiForm:setSelectedIndexById(data.id);
                uiForm:redraw();
                uiForm.lastUIType = "hand_book";
                uiForm.lastUIPage = self.pageType;
                uiForm.lastUIIndex = self.selectIndex;
                NewAirShipM.setSelectedAirShip(data.id);

                -- 界面特效
                uiForm:ctPopUpFromCenter();
                FormEffectM.ctPopUpFromCenter(uiForm);
            end

            -- 刷新下topMenu
            local uiTop  = UIMgr.getCurrentScene():getFormByName("UITopMenu");
            uiTop:updateNewFragment();
            uiTop:updateNewAirShipInfo();

            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UIAirShipHandBook");
        end
    end
    btnTurn:addTouchEventListener(onTurnClick);
    TextStyleM.setTextStyle(btnTurn, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnTurn:setTitleText(getLocStr("btn_text_turn"));

    -- 注册评论按钮点击事件
    local btnComment = findChildByName(self.node, "BT/btn_comment");
    local function onCommentClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");

            local info = self.typeData[self.pageType][self.selectIndex];

            -- 评论界面参数
            local data = {
                ["title"] = NewAirShipM.query(info.id, "name"),
                ["type"] = "ship_" .. tostring(info.id),
            }

            -- 打开评论界面
            UIMgr.getCurrentScene():removeFormByName("UIComment");
            local uiComment = UIComment.create(data);
            UIMgr.getCurrentScene():addForm(uiComment);
        end
    end
    btnComment:addTouchEventListener(onCommentClick);
end

-- 重绘评论按钮
function UIAirShipHandBook:redrawCommentBtn(para)
    local btnComment = findChildByName(self.node, "BT/btn_comment");

    local info = self.typeData[self.pageType][self.selectIndex];
    local commentType = "ship_" .. tostring(info.id);

    if not para then
        Operation.cmd_get_comment_counts(commentType);
    end

    if para and para.commentType ~= commentType then
        return;
    end

    local count = CommentM.getCommentCount(commentType);

    local kerning = 1;
    if getLang() == "zh" or getLang == "tw" then
        kerning = 5;
    end

    TextStyleM.setTextStyle(btnComment, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, kerning);
    btnComment:setTitleText(string.format(getLocStr("btn_text_comment_num"), count));
end

-- 绘制标签页
function UIAirShipHandBook:redrawTabs()
    local tabNode = findChildByName(self.node, "CT/tab");

    -- 标签页数量（总览+阵营数）
    local tabNum = TAB_NUM;

    -- 先移除旧的标签
    tabNode.rows = {};
    tabNode:removeAllChildren();

    -- 根据tab数据，生成新标签
    local widget = replaceNodeWithWidget(cc.CSLoader:createNode("layout/tab/tab.csb"));

    -- 置灰颜色
    local blendColor = TextStyleM.TEXT_COLOR_BLEND;
    local normalColor = TextStyleM.TEXT_COLOR_NORMAL;

    for i = 1, tabNum do
        local child = widget:clone();
        child:setName("tab" .. i);
        child.type = TAB_ORDER[i];

        self:registerTabTouchEvent(child);

        -- 计算单元格坐标
        -- 这个坐标将是单元格的描点所在
        local x = (i - 1) * 68 + 55;
        local y = 75;

        child:setPositionX(x);
        child:setPositionY(y);

        local tabLight = findChildByName(child, "light");
        local tabImage = findChildByName(child, "tab");
        tabLight:setScaleX(0.7);
        tabImage:setScaleX(0.7);

        local tabText = findChildByName(child, "text");
        local tabIcon = findChildByName(child, "icon");

        tabText:setVisible(false);
        tabIcon:setScale(0.9);
        tabIcon:setPositionY(tabIcon:getPositionY());

        if i == 1 then
            tabImage:loadTexture(getTabIconPath("red"));
            tabIcon:loadTexture(getAirShipHandBookImg("all"));
        else
            tabIcon:loadTexture(getAirShipHandBookImg(typeIndexMap[TAB_ORDER[i]]));
        end

        if i == 4 then
            tabIcon:setPositionY(tabIcon:getPositionY() + 2);
        end

        if TAB_ORDER[i] == self.pageType then
            tabLight:setVisible(true);
            tabIcon:setColor(normalColor);
            tabImage:setColor(normalColor);
        else
            tabLight:setVisible(false);
            tabIcon:setColor(blendColor);
            tabImage:setColor(blendColor);
        end

        tabNode:addChild(child)
        table.insert(tabNode.rows, child)
    end

    for i = 1, #tabNode.rows do
        local tab = tabNode.rows[i];
        tab:setPositionY(tab:getPositionY() + 100);
    end

    performWithDelay(self, function() self:playTabEffect(); end, 0.2);
end

-- 页签动画效果
function UIAirShipHandBook:playTabEffect()
    local tabNode = findChildByName(self.node, "CT/tab");
    -- 带窗口动画播放结束后，页签从上面往下掉
    for i = 1, #tabNode.rows do
        local tab = tabNode.rows[i];
        local pos = cc.p(tab:getPosition());
        local delay = cc.DelayTime:create(0.15 * (i - 1));
        local moveDown = cc.MoveTo:create(0.15, cc.p(pos.x, pos.y - 100 - 5));
        local moveBack = cc.MoveTo:create(0.15, cc.p(pos.x, pos.y - 100));
        local action = cc.Sequence:create(delay, moveDown, moveBack);
        tab:runAction(action);
    end
end

-- 重绘页面
function UIAirShipHandBook:redraw()
    local pageType = self.pageType;
    local typeData = self.typeData;

    -- 标题
    local titleLabel = findChildByName(self.CT, "title_label");
    local titleStr = getLocStr("ship_handbook_title_" .. self.pageType);
    titleLabel:getVirtualRenderer():setHorizontalAlignment(cc.TEXT_ALIGNMENT_CENTER);
    TextStyleM.setTextStyle(titleLabel, 34, TextStyleM.TEXT_COLOR_ORANGE, true, -2, nil, nil, nil, TextStyleM.TEXT_SIZE_MIDDLE2, true, 1);
    TextStyleM.setShadowStyle(titleLabel, cc.size(0, -3));
    TextStyleM.setOutlineStyle(titleLabel, 1.5, TextStyleM.TEXT_OUTLINE_COLOR, true);
    titleLabel:setString(titleStr);

    -- 副标题
    local subTitle = findChildByName(self.CT, "sub_title");
    local typeNum = #typeData[pageType];
    local ownNum;
    if self.pageType == TYPE_ALL then
        ownNum = #NewAirShipM.getOwnShips();
    else
        ownNum  = #NewAirShipM.getOwnTypeShip(pageType);
    end

    local subStr = string.format(getLocStr("ship_handbook_subtitle"), ownNum, typeNum);
    TextStyleM.setTextStyle(subTitle, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, -2);
    TextStyleM.setShadowStyle(subTitle, cc.size(0, -3));
    TextStyleM.setOutlineStyle(subTitle, 1.5, TextStyleM.TEXT_OUTLINE_COLOR, true);
    subTitle:setString(subStr);

    -- 副标题位置自适应
    adjustTitlePos(titleLabel, subTitle, 0, titleStr, subStr);

    subTitle:setPositionY(titleLabel:getPositionY() - 3);

    -- 重绘按钮
    self:redrawTurnBtn();
    self:redrawCommentBtn();
end

-- 重绘单个飞艇节点
function UIAirShipHandBook:initShipItem(child, index)
    -- 图标纵向偏移
    local offsetY = 11;

    -- 背景
    local bgImg = child:getChildByName("bg");
    local bgImgGray = child:getChildByName("gray_bg");

    -- 更改一下灰色背景图
    bgImg:setVisible(false);
    bgImgGray:setVisible(false);

    -- 图标
    local iconImage = child:getChildByName("icon");
    iconImage:setPosition(self.iconPosX + 14, self.iconPosY + offsetY);
    iconImage:setScale(0.8);

    -- 星级
    local starImage = child:getChildByName("rank");
    starImage:setVisible(false);

    -- 提示
    local tipImage = child:getChildByName("tip");
    tipImage:setVisible(false);

    -- 系别
    local departImg = child:getChildByName("depart_img");
    departImg:setVisible(false);

    local data = self.typeData[self.pageType][index];
    -- 已有飞艇直接画出来
    if data.own == 1 then
        -- 图标
        bgImg:setVisible(true);
        iconImage:loadTexture(getAirShipBookIconPath(data.id), 1);

        -- 星级
        starImage:setVisible(true);
        starImage:setPositionY(starImage:getPositionY());
        local tStar = createStarLayer(data.star, "images/ui/symbol/star_little.png","center", -0.5);
        if tStar then
            starImage:removeAllChildren();
            starImage:addChild(tStar);
        end
    -- 否则
    else
        -- 虚影
        iconImage:loadTexture(getAirShipBookIconPath(data.id), 1);
        setGrayMode(iconImage, true);
        iconImage:setOpacity(180);
        bgImg:setVisible(true);
        bgImg:setOpacity(140);
        starImage:setVisible(false);
        tipImage:setVisible(false);
    end

    -- 选中效果
    local focusBg = child:getChildByName("focus");
    if self.selectIndex == index then
        focusBg:setVisible(true);
    else
        focusBg:setVisible(false);
    end

    return child;
end

-- 注册格子点击事件
function UIAirShipHandBook:registerItemTouchEvent(node)
    local image = node:getChildByName("bg");
    local grayImage = node:getChildByName("gray_bg");
    local icon = node:getChildByName("icon");

    local function onClick(sender, eventType)
        -- 点击时的回调
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");

            local lastSelected = self.selectIndex;

            self.selectIndex = node.index;

            self:shipSelected(lastSelected, node.index);
        end
    end

    image:addTouchEventListener(onClick);
    grayImage:addTouchEventListener(onClick);
end

-- 格子选中效果
function UIAirShipHandBook:shipSelected(lastSelected, nowSelected)
    -- 清除上次选中效果
    local lastSel = self.scrollView:getChildByName(ITEM_NAME .. lastSelected);
    if lastSel then
        local focusBg = lastSel:getChildByName("focus");
        focusBg:setVisible(false);
    end

    -- 新选中的效果
    local nowSel = self.scrollView:getChildByName(ITEM_NAME .. nowSelected);
    if nowSel then
        local nowFocusBg = nowSel:getChildByName("focus");
        nowFocusBg:setVisible(true);
    end

    -- 重绘按钮
    self:redrawTurnBtn();
    self:redrawCommentBtn();
end

-- 重绘容器
function UIAirShipHandBook:redrawGrids()
    self.scrollView:jumpToTop();

    local w = DESIGN_WIDTH;
    local h = DESIGN_HEIGHT;

    -- 图标间距(横向)
    local wGap = 10;

    -- 图标间距(纵向)
    local hGap = 8;

    -- 图标宽度
    local iconWidth = 120;

    -- 图片高度
    local iconHeight = 120;

    local topHGap  = 10;
    local leftWGap = 5;
    local bottomHGap = 20;

    -- 当前类型的飞艇个数
    local shipNum = #self.typeData[self.pageType];

    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();

    local itemNode = cc.CSLoader:createNode("layout/sky_city/ShipItem.csb");
    itemNode:setScale(0.88);

    -- 获取icon的位置
    local iconNode = findChildByName(itemNode, "icon");
    self.iconPosY = iconNode:getPositionY();
    self.iconPosX = iconNode:getPositionX();

    -- @param windowNode    界面节点
    -- @param scrollNode    容器节点
    -- @param itemNode      单元格的节点
    -- @param totalNum      单元格总数
    -- @param pageColNum    单页可以显示下的列数
    -- @param wGap          单元格间距(横向) 这里作为最小值使用
    -- @param hGap          单元格间距(纵向)
    -- @param iconWidth     单元格宽度
    -- @param iconHeight    单元格高度
    -- @param topHGap       上方留
    -- @param leftWGap      左右留白  这里作为最小值使用
    -- @param touchEvent    点击事件注册函数
    ScrollTool.initScrollGridsVertical(self, self.scrollView, itemNode, shipNum, MIN_GRID_COLUMN, wGap, hGap, iconWidth, iconHeight, topHGap, bottomHGap, leftWGap, self.registerItemTouchEvent, self.initShipItem);
end

-- 重绘跳转按钮
function UIAirShipHandBook:redrawTurnBtn()
    local turnBtn = findChildByName(self.BT, "turn_btn");
    local data = self.typeData[self.pageType][self.selectIndex] or {};

    -- 拥有显示跳转，没有隐藏
    if data.own == 1 or data.chip == 1 then
        turnBtn:setVisible(true);
    else
        turnBtn:setVisible(false);
    end
end

-- 显示提示页面
function UIAirShipHandBook:showDesc()
    closeFormByName("UIShipDesc");
    local uiForm = UIShipDesc.create();
    UIMgr.getCurrentScene():addForm(uiForm);
end

-- 适配
function UIAirShipHandBook:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end
